#include "VSCLObject.h"
#include "VSController.h"
#include "VSMath.h"
#include "VSStream.h"
#include "VSGraphicInclude.h"
using namespace VSEngine2;
IMPLEMENT_RTTI_NoCreateFun(VSCLObject,VSObject)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSCLObject)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END
BEGIN_ADD_PROPERTY(VSCLObject,VSObject)
REGISTER_PROPERTY(m_bEnable,Enable,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_ControllerArray,ControllerArray,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_bIsStatic,IsStatic,VSProperty::F_SAVE_LOAD_CLONE);
REGISTER_PROPERTY(m_bIsChanged,IsChanged,VSProperty::F_SAVE_LOAD_CLONE);
END_ADD_PROPERTY
VSCLObject::VSCLObject()
{
	m_ControllerArray.Clear();
	m_bIsStatic = 1;
	m_bIsChanged = true;
	m_bEnable = true;
}
VSCLObject::~VSCLObject()
{

	DeleteAllController();
}

bool VSCLObject::AddController(VSController * pController)
{
	if(!pController)
		return false;
	for(unsigned int i = 0 ; i < m_ControllerArray.GetNum(); i++)
	{
		if(m_ControllerArray[i] == pController)
			return 1;
	}
	if(!pController->SetObject(this))
		return false;
	m_ControllerArray.AddElement(pController);
	
	m_bIsStatic = 0;
	return 1;
}

VSController * VSCLObject::DeleteController(unsigned int ID)
{
	if(ID >= m_ControllerArray.GetNum())
		return NULL;
	VSController * Temp = m_ControllerArray[ID];
	m_ControllerArray.Erase(ID);

	Temp->SetObject(NULL);
	return Temp;
}

unsigned int VSCLObject::DeleteController(VSController *pController)
{
	if(!pController)
		return VSMAX_INTEGER;
	for(unsigned int i = 0 ; i < m_ControllerArray.GetNum() ; i++)
	{

		if(m_ControllerArray[i] == pController)
		{
			pController->SetObject(NULL);
			m_ControllerArray.Erase(i);

			return i;
		}
	}

	return VSMAX_INTEGER;
}

void VSCLObject::DeleteAllController()
{
	for(unsigned int i = 0 ; i < m_ControllerArray.GetNum() ; i++)
	{

		m_ControllerArray[i]->SetObject(NULL);

	}
	m_ControllerArray.Clear();
}

VSController *VSCLObject::GetController(unsigned int ID)const
{
	if(ID >= m_ControllerArray.GetNum())
		return NULL;
	return m_ControllerArray[ID];
}

void VSCLObject::UpdateController(double dAppTime)
{
	if(m_bEnable)
	{
		for(unsigned int i = 0 ; i < m_ControllerArray.GetNum();i++)
		{
			m_ControllerArray[i]->SetObject(this);
			m_ControllerArray[i]->Update(dAppTime);

		}
	}

}

unsigned int  VSCLObject::DiskUse()const 
{
	unsigned int uiDistUse = VSObject::DiskUse();

	//controller
	uiDistUse += sizeof(unsigned int);
	uiDistUse += sizeof(VSController *) * (unsigned int)m_ControllerArray.GetNum();
	uiDistUse += sizeof(bool) * 2;
	uiDistUse += sizeof(bool);
	return uiDistUse;

}

bool VSCLObject::Clone(const VSObject * pObject,unsigned int uiType)
{


	const VSCLObject* Temp = DynamicCast<VSCLObject>(pObject); 
	if(!Temp)
		return 0;
	if(VSObject::Clone(pObject,uiType))
	{
		m_ControllerArray.Clear();
		m_bIsChanged = Temp->m_bIsChanged;
		m_bIsStatic = Temp->m_bIsStatic;
		m_bEnable = Temp->m_bEnable;

		m_ControllerArray.Clear();
		m_ControllerArray.SetBufferNum(Temp->m_ControllerArray.GetNum());
		for(unsigned int i = 0 ; i < Temp->m_ControllerArray.GetNum() ; i++)
		{
			VSController * pTemp1  = Temp->m_ControllerArray[i];
			VSController * pTemp2 =(VSController *)VSObject::GetInstance((pTemp1)->GetType().GetName());
			pTemp2->SetObject(this);
			pTemp2->Clone(pTemp1,uiType);
			
			m_ControllerArray[i] = pTemp2;
		}


		return 1;	
	}
	else
		return 0;


}

bool VSCLObject::Save(VSStream & rStream,unsigned int &iSaveUse)const
{

	if(!VSObject::Save(rStream,iSaveUse))
		return 0;

	if(!rStream.Write(&m_bEnable,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);
	unsigned int uiSize = m_ControllerArray.GetNum();
	if(!rStream.Write(&uiSize,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	
	for(unsigned int i = 0; i < m_ControllerArray.GetNum() ; i++)
	{
// 		VSController * iTemp = m_ControllerArray[i];
// 		if(!rStream.Write(&iTemp,sizeof(VSController *)))
// 			return 0;
		if(!rStream.WriteObjectPtr(m_ControllerArray[i]))
			return 0;
		iSaveUse += sizeof(VSController *);
	}
	
	if(!rStream.Write(&m_bIsStatic,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	if(!rStream.Write(&m_bIsChanged,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);
	return 1;
}

bool VSCLObject::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSObject::Load(rStream,iSaveUse))
		return 0;

	if(!rStream.Read(&m_bEnable,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);
	unsigned int uiSize;
	if(!rStream.Read(&uiSize,sizeof(unsigned int)))
		return 0;
	iSaveUse += sizeof(unsigned int);

	m_ControllerArray.SetBufferNum(uiSize);
	for(unsigned int i = 0; i < uiSize ; i++)
	{
// 		VSController * iTemp = NULL;
// 		if(!rStream.Read(&iTemp,sizeof(VSController *)))
// 			return 0;
// 		AddLink(iTemp);
		if(!rStream.ReadObjectPtr(m_ControllerArray[i]))
			return 0;
		iSaveUse += sizeof(VSController *);

	}

	if(!rStream.Read(&m_bIsStatic,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);

	if(!rStream.Read(&m_bIsChanged,sizeof(bool)))
		return 0;
	iSaveUse += sizeof(bool);
	return 1;
}

bool VSCLObject::Link(VSStream & rStream)
{
	if(!VSObject::Link(rStream))
		return 0;
	
	for(unsigned int i = 0 ; i < m_ControllerArray.GetNum() ; i++)
	{

		//m_ControllerArray[i] = (VSController*)rStream.GetMapValue(GetNextLink());
		rStream.LinkObjectPtr(m_ControllerArray[i]);
		if(!m_ControllerArray[i])
			return 0;

	}
	return 1;
}

bool VSCLObject::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSObject::Register(rStream))
		return 0;
	for(unsigned int i = 0 ; i < m_ControllerArray.GetNum() ; i++)
	{
		if(m_ControllerArray[i])
		{
			if(!m_ControllerArray[i]->Register(rStream))
				return 0;
		}
	}
	return 1;
}
void VSCLObject::ClearAllTime()
{
	for (unsigned int i = 0 ; i < m_ControllerArray.GetNum() ; i++)
	{
		m_ControllerArray[i]->ClearTime();
	}
}